home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jovept1.arc / FUNCS.C < prev    next >
Text File  |  1985-05-30  |  21KB  |  852 lines

  1. /* funcs.c */
  2.  
  3. /* JOVE/MSDOS. K. Mitchum 1/85 */
  4. /* Modifications for personal use only. */
  5. /* original code J. Payne LSRHS 5/83 */
  6. /* Ken Mitchum */
  7. /* University of Pittsburgh */
  8. /* Decision Systems Laboratory */
  9.  
  10.  
  11. /*
  12.    Jonathan Payne at Lincoln-Sudbury Regional High School 4-19-83
  13.  
  14.    jove_funcs.c
  15.  
  16.    This is like the second half of jove_extend.c.  It was divided
  17.    because the file was taking too long to compile ...  */
  18.  
  19. #define FUNCS
  20.  
  21. #include "jove.h"
  22. #include "funcs.h"
  23. #include "files.h"
  24.  
  25. static int    nfuncs = 0,
  26.         nmacros = 0,
  27.         nvars = 0;
  28.  
  29.  
  30. tmany(str)
  31. char    *str;
  32. {
  33.     complain("too many %s", str);
  34. }
  35.  
  36. DefFunc(name, func)
  37. char    *name;
  38. int    (*func)();
  39. {
  40.     if (nfuncs >= NFUNCS)
  41.         tmany("functions");
  42.     functions[nfuncs].f_name = name;
  43.     functions[nfuncs].f.Func = func;
  44.     functions[nfuncs].f_type = FUNCTION;
  45.     nfuncs++;
  46. }
  47.  
  48. DefVar(name, varptr)
  49. char    *name;
  50. int    *varptr;
  51. {
  52.     if (nvars >= NVARS)
  53.         tmany("variables");
  54.     variables[nvars].f_name = name;
  55.     variables[nvars].f.Var = varptr;
  56.     variables[nvars].f_type = VARIABLE;
  57.     nvars++;
  58. }
  59.  
  60. DefMac(name, macptr)
  61. char    *name;
  62. FMACRO    *macptr;
  63. {
  64.     if (nmacros > NVARS)
  65.         tmany("macros");
  66.     macros[nmacros].f_name = name;
  67.     macros[nmacros].f.Macro = macptr;
  68.     macros[nmacros].f_type = MACRO;
  69.     nmacros++;
  70. }
  71.  
  72. extern int
  73.     EscPrefix(),
  74.     CtlxPrefix(),
  75.     AppReg(),
  76.     Apropos(),
  77.     BackChar(),
  78.     Bparen(),
  79.     BackWord(),
  80.     Bof(),
  81.     Bol(),
  82.     Bos(),
  83.     Bow(),
  84.     BindAKey(),
  85.     BindMac(),
  86.     BufPos(),
  87.     UnBound(),
  88.     CasRegLower(),
  89.     CasRegUpper(),
  90.     CapWord(),
  91.     LowWord(),
  92.     UppWord(),
  93.     ChrToOct(),
  94.     ClAndRedraw(),
  95.     CopyRegion(),
  96.     CTab(),
  97.     DelBlnkLines(),
  98.     DelNChar(),
  99.     DelNWord(),
  100.     OneWindow(),
  101.     DelPChar(),
  102.     DelPWord(),
  103.     DelReg(),
  104.     DelWtSpace(),
  105.     DelCurWindow(),
  106.     KeyDesc(),
  107.     DescCom(),
  108.     Eof(),
  109.     Eol(),
  110.     Eos(),
  111.     Eow(),
  112.     BufErase(),
  113.     PtToMark(),
  114.     Extend(),
  115.     ExecMacro(),
  116.     RunMacro(),
  117.     Leave(),
  118.     FindFile(),
  119.     VisitFile(),
  120.     WindFind(),
  121.     FindTag(),
  122.     ToIndent(),
  123.     ForChar(),
  124.     Fparen(),
  125.     ForWord(),
  126.     FourTime(),
  127.     GoLine(),
  128.     GrowWindow(),
  129.     IncFSearch(),
  130.     IncRSearch(),
  131.     InsFile(),
  132.     InitBindings(),
  133.     Justify(),
  134.     BufKill(),
  135.     KillEOL(),
  136.     BufList(),
  137.     NotModified(),
  138.     NameMac(),
  139.     Newline(),
  140.     OpenLine(),
  141.     LineAI(),
  142.     NextLine(),
  143.     NextPage(),
  144.     NextWindow(),
  145.     OverWrite(),
  146.     PopMark(),
  147.     PageNWind(),
  148.     DoParen(),
  149.     DoBrace(),
  150.     PauseJove(),
  151.     PrevLine(),
  152.     PrevPage(),
  153.     PrevWindow(),
  154.     QRepSearch(),
  155.     QuotChar(),
  156.     ReadFile(),
  157.     ReadMacs(),
  158.     RedrawDisplay(),
  159.     ReInitTTY(),
  160.     RepSearch(),
  161.     Beep(),
  162.     DownScroll(),
  163.     UpScroll(),
  164.     ForSearch(),
  165.     RevSearch(),
  166.     SelBuf(),
  167.     SelfInsert(),
  168.     SetVar(),
  169.     SetMark(),
  170. #ifdef UNIX
  171.     ShToBuf(),
  172. #endif
  173.     ShrWindow(),
  174.     Source(),
  175.     SplitWind(),
  176.     Remember(),
  177.     Forget(),
  178.     StrLength(),
  179.     PauseJove(),
  180.     TextInsert(),
  181.     TransChar(),
  182.     UnBound(),
  183.     VtKeys(),
  184.     SaveFile(),
  185.     WtModBuf(),
  186.     WriteFile(),
  187.     WriteMacs(),
  188.     WrtReg(),
  189.     Yank(),
  190.     YankPop(),
  191.     PrVar(),
  192.     SetQchars(),
  193.     WNumLines();
  194.  
  195. #ifdef UNIX
  196. extern int
  197.     CParse(),
  198.     LintParse(),
  199.     SpellCom(),
  200.     NextError(),
  201.     MakeErrors(),
  202.     ShellCom(),
  203.     RegToShell();
  204. #endif
  205.  
  206. InitFuncs()
  207. {
  208.     DefFunc("Prefix-1", EscPrefix);
  209.     DefFunc("Prefix-2", CtlxPrefix);
  210.     DefFunc("append-region", AppReg);
  211.     DefFunc("apropos", Apropos);
  212.     DefFunc("backward-char", BackChar);
  213.     DefFunc("backward-paren", Bparen);
  214.     DefFunc("backward-word", BackWord);
  215.     DefFunc("beginning-of-file", Bof);
  216.     DefFunc("beginning-of-line", Bol);
  217.     DefFunc("beginning-of-sentence", Bos);
  218.     DefFunc("beginning-of-window", Bow);
  219.     DefFunc("bind-to-key", BindAKey);
  220.     DefFunc("bind-macro-to-key", BindMac);
  221.     DefFunc("buffer-position", BufPos);
  222.     DefFunc("case-region-lower", CasRegLower);
  223.     DefFunc("case-region-upper", CasRegUpper);
  224.     DefFunc("case-word-capitalize", CapWord);
  225.     DefFunc("case-word-lower", LowWord);
  226.     DefFunc("case-word-upper", UppWord);
  227.     DefFunc("char-to-octal-insert", ChrToOct);
  228.     DefFunc("clear-and-redraw", ClAndRedraw);
  229.     DefFunc("copy-region", CopyRegion);
  230.     DefFunc("c-tab", CTab);
  231.     DefFunc("delete-blank-lines-around-point", DelBlnkLines);
  232.     DefFunc("delete-next-char", DelNChar);
  233.     DefFunc("delete-next-word", DelNWord);
  234.     DefFunc("delete-other-windows", OneWindow);
  235.     DefFunc("delete-previous-char", DelPChar);
  236.     DefFunc("delete-previous-word", DelPWord);
  237.     DefFunc("delete-to-killbuffer", DelReg);
  238.     DefFunc("delete-white-space", DelWtSpace);
  239.     DefFunc("delete-current-window", DelCurWindow);
  240.     DefFunc("describe-key", KeyDesc);
  241.     DefFunc("describe-command", DescCom);
  242.     DefFunc("end-of-file", Eof);
  243.     DefFunc("end-of-line", Eol);
  244.     DefFunc("end-of-sentence", Eos);
  245.     DefFunc("end-of-window", Eow);
  246.     DefFunc("erase-buffer", BufErase);
  247.     DefFunc("exchange-point-and-mark", PtToMark);
  248.     DefFunc("execute-extended-command", Extend);
  249.     DefFunc("execute-keyboard-macro", ExecMacro);
  250.     DefFunc("execute-macro", RunMacro);
  251.     DefFunc("exit-jove", Leave);
  252.     DefFunc("find-file", FindFile);
  253.     DefFunc("find-file-in-other-window", WindFind);
  254.     DefFunc("find-tag", FindTag);
  255.     DefFunc("first-non-blank", ToIndent);
  256.     DefFunc("forward-char", ForChar);
  257.     DefFunc("forward-paren", Fparen);
  258.     DefFunc("forward-word", ForWord);
  259.     DefFunc("four-times", FourTime);
  260.     DefFunc("goto-line", GoLine);
  261.     DefFunc("grow-window", GrowWindow);
  262.     DefFunc("i-search-forward", IncFSearch);
  263.     DefFunc("i-search-reverse", IncRSearch);
  264.     DefFunc("insert-file", InsFile);
  265.     DefFunc("init-bindings", InitBindings);
  266.     DefFunc("justify-paragraph", Justify);
  267.     DefFunc("kill-buffer", BufKill);
  268.     DefFunc("kill-to-end-of-line", KillEOL);
  269.     DefFunc("list-buffers", BufList);
  270.     DefFunc("make-buffer-unmodified", NotModified);
  271.     DefFunc("name-keyboard-macro", NameMac);
  272.     DefFunc("newline", Newline);
  273.     DefFunc("newline-and-backup", OpenLine);
  274.     DefFunc("newline-and-indent", LineAI);
  275.     DefFunc("next-line", NextLine);
  276.     DefFunc("next-page", NextPage);
  277.     DefFunc("next-window", NextWindow);
  278.     DefFunc("number-lines-in-window", WNumLines);
  279.     DefFunc("replace-char", OverWrite);
  280.     DefFunc("page-next-window", PageNWind);
  281.     DefFunc("paren-flash", DoParen);
  282.     DefFunc("brace-magic", DoBrace);
  283.     DefFunc("pause-jove", PauseJove);
  284.     DefFunc("pop-mark", PopMark);
  285.     DefFunc("previous-line", PrevLine);
  286.     DefFunc("previous-page", PrevPage);
  287.     DefFunc("previous-window", PrevWindow);
  288.     DefFunc("print", PrVar);
  289.     DefFunc("query-replace-search", QRepSearch);
  290.     DefFunc("quote-char", QuotChar);
  291.     DefFunc("read-file", ReadFile);
  292.     DefFunc("read-macros-from-file", ReadMacs);
  293.     DefFunc("redraw-display", RedrawDisplay);
  294.     DefFunc("reinitialize-terminal", ReInitTTY);
  295.     DefFunc("replace-search", RepSearch);
  296.     DefFunc("ring-the-bell", Beep);
  297.     DefFunc("scroll-down", DownScroll);
  298.     DefFunc("scroll-up", UpScroll);
  299.     DefFunc("search-forward", ForSearch);
  300.     DefFunc("search-reverse", RevSearch);
  301.     DefFunc("select-buffer", SelBuf);
  302.     DefFunc("self-insert", SelfInsert);
  303.     DefFunc("set", SetVar);
  304.     DefFunc("set-mark", SetMark);
  305.     DefFunc("set-quote-characters", SetQchars);
  306. #ifdef UNIX
  307.     DefFunc("shell-command-to-buffer", ShToBuf);
  308. #endif
  309.     DefFunc("shrink-window", ShrWindow);
  310.     DefFunc("source", Source);
  311.     DefFunc("split-current-window", SplitWind);        
  312.     DefFunc("start-remembering", Remember);
  313.     DefFunc("stop-remembering", Forget);        /* Not bad */
  314.     DefFunc("string-length", StrLength);
  315.     DefFunc("suspend-jove", PauseJove);
  316.     DefFunc("text-insert", TextInsert);
  317.     DefFunc("transpose-chars", TransChar);
  318.     DefFunc("unbound", UnBound);
  319.     DefFunc("visit-file", VisitFile);
  320.     DefFunc("vt100-arrow-keys", VtKeys);
  321.     DefFunc("write-current-file", SaveFile);
  322.     DefFunc("write-macros-to-file", WriteMacs);
  323.     DefFunc("write-modified-files", WtModBuf);
  324.     DefFunc("write-named-file", WriteFile);
  325.     DefFunc("write-region", WrtReg);
  326.     DefFunc("yank", Yank);
  327.     DefFunc("yank-pop", YankPop);
  328.     DefFunc((char *) 0, (int (*)()) 0);
  329. #ifdef UNIX
  330.     DefFunc("parse-C-errors", CParse);
  331.     DefFunc("parse-LINT-errors", LintParse);
  332.     DefFunc("spell-buffer", SpellCom);
  333.     DefFunc("next-error", NextError);
  334.     DefFunc("compile-it", MakeErrors);
  335.     DefFunc("shell-command", ShellCom);
  336.     DefFunc("filter-region", RegToShell);
  337. #endif
  338.  
  339.     DefVar("allow-^S-and-^Q", &OKXonXoff);
  340.     DefVar("auto-indent", &globflags[AUTOIND]);
  341.     DefVar("c-mode", &globflags[CMODE]);
  342.     DefVar("case-independent-search", &globflags[CASEIND]);
  343.     DefVar("files-should-end-with-newline", &EndWNewline);
  344.     DefVar("internal-tabstop", &tabstop);
  345.     DefVar("magic", &globflags[MAGIC]);
  346.     DefVar("make-all-at-once", &MakeAll);
  347.     DefVar("over-write", &globflags[OVERWRITE]);
  348.     DefVar("physical-tabstop", &phystab);
  349.     DefVar("right-margin", &RMargin);
  350.     DefVar("show-match", &globflags[MATCHING]);
  351.     DefVar("scroll-step", &ScrollStep);
  352.     DefVar("text-fill", &globflags[TEXTFILL]);
  353.     DefVar("use-temporary-buffers", &UseBuffers);
  354.     DefVar("visible-bell", &VisBell);
  355.     DefVar("write-files-on-make", &WtOnMk);
  356.     DefVar((char *) 0, (int *) 0);
  357. };
  358.  
  359. FUNCT *
  360. FindFunc(func)
  361. register int     (*func)();
  362. {
  363.     register FUNCT    *fp;
  364.  
  365.       for (fp = functions; fp->f_name; fp++)
  366.         if (fp->f_type == FUNCTION && fp->f.Func == func)
  367.             return fp;
  368.     return 0;
  369. }
  370.  
  371. BindFunc(map, letter, func)
  372. FUNCT *map[];
  373. int    (*func)();
  374. {
  375.     static FUNCT    *fp = 0;
  376.  
  377.     if (!fp || fp->f.Func != func)
  378.         fp = FindFunc(func);
  379.     map[letter] = fp;
  380. }
  381.  
  382. ZeroMap(map)
  383. FUNCT *map[];
  384. {
  385.     int    i;
  386.  
  387.     for (i = 0; i < 0200; i++)
  388.         map[i] = 0;
  389. }
  390.  
  391. BindInserts(func)
  392. FUNC func;
  393. {
  394.     register int    i;
  395.  
  396.     for (i = ' '; i < 0177; i++)
  397.         BindFunc(mainmap, i, func);
  398.     BindFunc(mainmap, CTL(I), func);
  399. }
  400.  
  401. InitBindings()
  402. {
  403.     BindInserts(SelfInsert);
  404.     /* Most just insert themselves */
  405.     BindFunc(mainmap, CTL(@), SetMark);
  406.     BindFunc(mainmap, CTL(A), Bol);
  407.     BindFunc(mainmap, CTL(B), BackChar);
  408.     BindFunc(mainmap, CTL(C), SetMark);
  409.     BindFunc(mainmap, CTL(D), DelNChar);
  410.     BindFunc(mainmap, CTL(E), Eol);
  411.     BindFunc(mainmap, CTL(F), ForChar);
  412.     BindFunc(mainmap, CTL(G), Beep);
  413.     BindFunc(mainmap, CTL(H), DelPChar);
  414.     BindFunc(mainmap, CTL(I), CTab);
  415.     BindFunc(mainmap, CTL(J), LineAI);
  416.     BindFunc(mainmap, CTL(K), KillEOL);
  417.     BindFunc(mainmap, CTL(L), RedrawDisplay);
  418.     BindFunc(mainmap, CTL(M), Newline);
  419.     BindFunc(mainmap, CTL(N), NextLine);
  420.     BindFunc(mainmap, CTL(O), OpenLine);
  421.     BindFunc(mainmap, CTL(P), PrevLine);
  422.     BindFunc(mainmap, CTL(Q), QuotChar);
  423.     BindFunc(mainmap, CTL(^), QuotChar);
  424.     BindFunc(mainmap, CTL(R), RevSearch);
  425.     BindFunc(mainmap, CTL(S), ForSearch);
  426.     BindFunc(mainmap, CTL(\\), ForSearch);
  427.     BindFunc(mainmap, CTL(T), TransChar);    
  428. /*    BindFunc(mainmap, CTL(U), FourTime); */
  429.     BindFunc(mainmap, CTL(U), EscPrefix);
  430.     BindFunc(mainmap, CTL(V), NextPage);
  431.     BindFunc(mainmap, CTL(W), DelReg);
  432.     BindFunc(mainmap, CTL(X), CtlxPrefix);
  433.     BindFunc(mainmap, CTL(Y), Yank);
  434.     BindFunc(mainmap, CTL(Z), UpScroll);
  435.     BindFunc(mainmap, CTL([), EscPrefix);
  436.     BindFunc(mainmap, ')', DoParen);
  437.     BindFunc(mainmap, '}', DoParen);
  438.     BindFunc(mainmap, '{', DoBrace);
  439.     BindFunc(mainmap, '\177', DelPChar);
  440.  
  441.     BindFunc(pref1map, CTL(B), Bparen);
  442.     BindFunc(pref1map, CTL(F), Fparen);
  443.     BindFunc(pref1map, CTL(L), ClAndRedraw);
  444.     BindFunc(pref1map, CTL(V), PageNWind);
  445.     BindFunc(pref1map, '>', Eof);
  446.     BindFunc(pref1map, '<', Bof);
  447.     BindFunc(pref1map, 'a', Bos);
  448.     BindFunc(pref1map, 'A', Bos);
  449.     BindFunc(pref1map, 'B', BackWord);
  450.     BindFunc(pref1map, 'b', BackWord);
  451.     BindFunc(pref1map, 'C', CapWord);
  452.     BindFunc(pref1map, 'c', CapWord);
  453.     BindFunc(pref1map, 'D', DelNWord);
  454.     BindFunc(pref1map, 'd', DelNWord);
  455.     BindFunc(pref1map, 'E', Eos);
  456.     BindFunc(pref1map, 'e', Eos);
  457.     BindFunc(pref1map, 'F', ForWord);
  458.     BindFunc(pref1map, 'f', ForWord);
  459.     BindFunc(pref1map, 'G', GoLine);
  460.     BindFunc(pref1map, 'g', GoLine);
  461.     BindFunc(pref1map, 'J', Justify);
  462.     BindFunc(pref1map, 'j', Justify);
  463.     BindFunc(pref1map, 'L', LowWord);
  464.     BindFunc(pref1map, 'l', LowWord);
  465.     BindFunc(pref1map, 'M', ToIndent);
  466.     BindFunc(pref1map, 'm', ToIndent);
  467.     BindFunc(pref1map, 'Q', QRepSearch);
  468.     BindFunc(pref1map, 'q', QRepSearch);
  469.     BindFunc(pref1map, 'R', RepSearch);
  470.     BindFunc(pref1map, 'r', RepSearch);
  471.     BindFunc(pref1map, 'V', PrevPage);
  472.     BindFunc(pref1map, 'v', PrevPage);
  473.     BindFunc(pref1map, 'U', UppWord);
  474.     BindFunc(pref1map, 'u', UppWord);
  475.     BindFunc(pref1map, 'W', CopyRegion);
  476.     BindFunc(pref1map, 'w', CopyRegion);
  477.     BindFunc(pref1map, 'X', Extend);
  478.     BindFunc(pref1map, 'x', Extend);
  479.     BindFunc(pref1map, 'Y', YankPop);
  480.     BindFunc(pref1map, 'y', YankPop);
  481.     BindFunc(pref1map, 'Z', DownScroll);
  482.     BindFunc(pref1map, 'z', DownScroll);
  483.     BindFunc(pref1map, '[', VtKeys);    /* Vt100 arrows */
  484.     BindFunc(pref1map, '\177', DelPWord);
  485.     BindFunc(pref1map, '\\', DelWtSpace);
  486.     BindFunc(pref1map, '~', NotModified);
  487.     BindFunc(pref1map, '.', Eow);
  488.     BindFunc(pref1map, ',', Bow);
  489.     BindFunc(pref1map, '?', Apropos);
  490.  
  491.     /* CTLX prefix */
  492.  
  493.     ZeroMap(pref2map);
  494.     BindFunc(pref2map, CTL(B), BufList);
  495.     BindFunc(pref2map, CTL(C), Leave);
  496.     BindFunc(pref2map, CTL(D), KeyDesc);
  497.     BindFunc(pref2map, CTL(F), FindFile);
  498.     BindFunc(pref2map, CTL(I), InsFile);
  499.     BindFunc(pref2map, CTL(L), CasRegLower);
  500.     BindFunc(pref2map, CTL(M), WtModBuf);
  501.     BindFunc(pref2map, CTL(O), DelBlnkLines);
  502.     BindFunc(pref2map, CTL(R), ReadFile);
  503.     BindFunc(pref2map, CTL(S), SaveFile);
  504.     BindFunc(pref2map, CTL(U), CasRegUpper);
  505.     BindFunc(pref2map, CTL(V), VisitFile);
  506.     BindFunc(pref2map, CTL(W), WriteFile);
  507.     BindFunc(pref2map, CTL(X), PtToMark);
  508.     BindFunc(pref2map, CTL(Z), GrowWindow);
  509.     BindFunc(pref2map, CTL(\\), SaveFile);
  510.     BindFunc(pref2map, '1', OneWindow);
  511.     BindFunc(pref2map, '2', SplitWind);
  512.     BindFunc(pref2map, '4', WindFind);
  513.     BindFunc(pref2map, 'B', SelBuf);
  514.     BindFunc(pref2map, 'b', SelBuf);
  515.     BindFunc(pref2map, 'c', StrLength);
  516.     BindFunc(pref2map, 'C', StrLength);
  517.     BindFunc(pref2map, 'D', DelCurWindow);
  518.     BindFunc(pref2map, 'd', DelCurWindow);
  519.     BindFunc(pref2map, 'E', ExecMacro);
  520.     BindFunc(pref2map, 'e', ExecMacro);
  521.     BindFunc(pref2map, 'K', BufKill);
  522.     BindFunc(pref2map, 'k', BufKill);
  523.     BindFunc(pref2map, 'N', NextWindow);
  524.     BindFunc(pref2map, 'n', NextWindow);
  525.     BindFunc(pref2map, 'O', PrevWindow);
  526.     BindFunc(pref2map, 'o', PrevWindow);
  527.     BindFunc(pref2map, 'P', PrevWindow);
  528.     BindFunc(pref2map, 'p', PrevWindow);
  529.     BindFunc(pref2map, 'R', IncRSearch);
  530.     BindFunc(pref2map, 'r', IncRSearch);
  531.     BindFunc(pref2map, 'S', IncFSearch);
  532.     BindFunc(pref2map, 's', IncFSearch);
  533.     BindFunc(pref2map, 'T', FindTag);
  534.     BindFunc(pref2map, 't', FindTag);
  535.     BindFunc(pref2map, '^', GrowWindow);
  536.     BindFunc(pref2map, '(', Remember);
  537.     BindFunc(pref2map, ')', Forget);
  538.  
  539. #ifdef UNIX
  540.     BindFunc(pref2map, CTL(N), NextError);
  541.     BindFunc(pref2map, CTL(E), MakeErrors);
  542.     BindFunc(pref2map, '!', ShellCom);
  543. #endif
  544. }
  545.  
  546. char *
  547. FuncName()
  548. {
  549.     static char    func[60];
  550.  
  551.     return sprintf(func, ": %s ", LastFunc->f_name);
  552. }
  553.  
  554. int    Interactive;    /* True when we invoke with the command handler? */
  555.  
  556. ExecFunc(fp, interactive)
  557. FUNCT *fp;
  558. {
  559.     int    bindinteract = Interactive;
  560.  
  561.     Interactive = interactive;
  562.     LastFunc = fp;
  563.     switch (fp->f_type) {
  564.     case MACRO:
  565.         DoMacro(fp->f.Macro);
  566.         break;
  567.  
  568.     case FUNCTION:
  569.         if (fp->f.Func)
  570.             (*fp->f.Func)();
  571.     }
  572.     Interactive = bindinteract;
  573. }
  574.  
  575. /* Can only define the keyboard macro.  IT can be renamed to another
  576.  * macro.  If the keyboard macro is renamed, we make a copy of it.
  577.  * The keyboard macro is ALWAYS the keyboard macro.
  578.  * 
  579.  * We can't define or run the same macro recursively.  Each macro has 
  580.  * a bit saying whether or not it is currently being executed/defined.
  581.  */
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588. char    *rem = "remember";
  589.  
  590. FixMacros()
  591. {
  592.     register int    i;
  593.     FMACRO    *mp;
  594.  
  595.     for (i = 0; macstack[i]; i++) {
  596.         mp = macstack[i];
  597.         macstack[i] = 0;
  598.         mp->Flags = mp->Offset = 0;
  599.     }
  600.     stackp = -1;
  601.     KeyMacro.Flags = KeyMacro.Offset = 0;
  602. }
  603.  
  604. MacErr(name1, name2)
  605. char    *name1,
  606.     *name2;
  607. {
  608.     KeyMacro.Flags = 0;
  609.     MacNolen(&KeyMacro);
  610.     complain("Can't %s recursively; no longer %sing", name1, name2);
  611. }
  612.  
  613. Remember()
  614. {
  615.     if (KeyMacro.Flags & DEFINE)
  616.         MacErr(rem, rem);
  617.     KeyMacro.Flags |= DEFINE;
  618.     MacNolen(&KeyMacro);
  619.     message("Remembering...");
  620. }
  621.  
  622. /* Is `c' a prefix character */
  623.  
  624. PrefChar(c)
  625. {
  626. #ifdef UNIX
  627.     return (mainmap[c]->f.Func == EscPrefix ||
  628.             mainmap[c]->f.Func == CtlxPrefix);
  629. #else
  630.     return (mainmap[c]->f.Func == eprefix ||
  631.             mainmap[c]->f.Func == cprefix);
  632. #endif
  633. }
  634.  
  635. Forget()
  636. {
  637.     char    *cp;
  638.     FMACRO    *m = &KeyMacro;
  639.  
  640.     if (m->Flags & DEFINE) {
  641.         message("Keyboard macro defined");
  642.         m->Flags &= ~DEFINE;
  643.         cp = &m->Body[m->MacLength - 2];
  644.         if (PrefChar(*cp))
  645.             m->MacLength -= 2;
  646. #ifdef UNIX
  647.         else if (functions[*++cp].f.Func == Forget)
  648. #else
  649.         else if (functions[*++cp].f.Func == frgt)
  650. #endif
  651.             m->MacLength--;
  652.     }
  653. }
  654.  
  655. ExecMacro()
  656. {
  657.     DoMacro(&KeyMacro);
  658. }
  659.  
  660. DoMacro(mac)
  661. FMACRO    *mac;
  662. {
  663.     if (mac->Flags & DEFINE)
  664.         MacErr("define", rem);
  665.     if (mac->Flags & EXECUTE)
  666.         MacErr("execute", "execut");
  667.     if (++stackp >= NMACROS)
  668.         complain("The impossible with macros just happened");
  669.     macstack[stackp] = mac;
  670.     mac->Offset = 0;
  671.     mac->Ntimes = exp;
  672.     mac->Flags |= EXECUTE;
  673. }
  674.  
  675. char *
  676. copystr(str)
  677. char    *str;
  678. {
  679.     char    *val = emalloc(strlen(str) + 1);
  680.  
  681.     strcpy(val, str);
  682.     return val;
  683. }
  684.  
  685. FMACRO *
  686. macexists(name)
  687. char    *name;
  688. {
  689.     register int    i;
  690.  
  691.     for (i = 0; i < nmacros; i++)
  692.         if (strcmp(macros[i].f.Macro->Name, name) == 0)
  693.             return macros[i].f.Macro;
  694.     return 0;
  695. }
  696.  
  697. NameMac()
  698. {
  699.     char    *name;
  700.     FMACRO    *m;
  701.  
  702.     if (KeyMacro.MacLength == 0)
  703.         complain("Define it first!");
  704.     if (KeyMacro.Flags & (DEFINE | EXECUTE))
  705.         complain("Can't name while defining/executing");
  706.     if ((m = macexists(name = ask((char *) 0, FuncName()))) == 0)
  707.         m = (FMACRO *) emalloc(sizeof *m);
  708.     else {
  709.         if (strcmp(name, KeyMacro.Name) == 0)
  710.             complain("Can't name it that!");
  711.         free(m->Name);
  712.         free(m->Body);
  713.     }
  714.     name = copystr(name);
  715. #ifdef UNIX
  716.     *m = KeyMacro;                /* Copy the keyboard macro */
  717. #else
  718.     m->MacLength = KeyMacro.MacLength;
  719.     m->MacBuflen = KeyMacro.MacBuflen;
  720. #endif
  721.     m->Body = emalloc(m->MacBuflen);
  722.     copynchar(m->Body, KeyMacro.Body, m->MacLength);
  723.     m->Ntimes = m->Flags = m->Offset = 0;    /* At the beginning */
  724.     m->Name = name;
  725.     DefMac(name, m);
  726. }    
  727.  
  728. copynchar(t, f, len)
  729. register char    *t,
  730.         *f;
  731. register int    len;
  732. {
  733.     while (len--)
  734.         *t++ = *f++;
  735. }
  736.  
  737. MacInit()
  738. {
  739.     SetMacro(&KeyMacro, "keyboard-macro");
  740.     FixMacros();
  741. }
  742.  
  743. MacNolen(m)
  744. FMACRO    *m;
  745. {
  746.     m->MacLength = m->Offset = 0;
  747. }
  748.  
  749. SetMacro(m, name)
  750. FMACRO    *m;
  751. char    *name;
  752. {
  753.     DefMac(name, m);    /* Try this before mallocing memory */
  754.     MacNolen(m);
  755.     m->Name = name;
  756.     m->MacBuflen = 16;
  757.     m->Body = emalloc(m->MacBuflen);
  758.     m->Ntimes = m->Flags = 0;
  759. }    
  760.  
  761. MacPutc(c)
  762. int    c;
  763. {
  764.     if (KeyMacro.MacLength >= KeyMacro.MacBuflen) {
  765.         KeyMacro.Body = realloc(KeyMacro.Body, (unsigned) KeyMacro.MacLength + 16);
  766.         if (KeyMacro.Body == 0)
  767.             MacErr("malloc", rem);
  768.         KeyMacro.MacBuflen += 16;
  769.     }
  770.     KeyMacro.Body[KeyMacro.Offset++] = c;
  771.     KeyMacro.MacLength++;
  772. }
  773.  
  774. MacGetc()
  775. {
  776.     if (macstack[stackp]->Offset == macstack[stackp]->MacLength) {
  777.         macstack[stackp]->Offset = 0;
  778.         if (--macstack[stackp]->Ntimes == 0) {
  779.             macstack[stackp]->Flags &= ~EXECUTE;
  780.             stackp--;
  781.         }
  782.         return (*Gtchar)();
  783.     }
  784.     return macstack[stackp]->Body[macstack[stackp]->Offset++];
  785. }
  786.  
  787. RunMacro()
  788. {
  789.     int    com;
  790.  
  791.     com = findcom(macros, FuncName());
  792.     if (com < 0)
  793.         return;
  794.     DoMacro(macros[com].f.Macro);
  795. }
  796.  
  797. WriteMacs()
  798. {
  799.     FUNCT *mp;
  800.     FMACRO    *m;
  801.     int    macfd,
  802.         namelen;
  803.     char    *file;
  804.  
  805.     file = ask((char *) 0, FuncName());
  806.     if ((macfd = creat(file, CREATMODE)) == -1)
  807.         complain(IOerr("create", file));
  808.     /* Don't write the keyboard macro which is always the first */
  809.     for (mp = ¯os[1]; mp < ¯os[NMACROS]; mp++) {
  810.         m = mp->f.Macro;
  811.         if (m == 0 || m->MacLength == 0)
  812.             continue;
  813.         ignore(write(macfd, (char *) &m->MacLength, sizeof m->MacLength));
  814.         namelen = strlen(m->Name) + 1;    /* Including the null */
  815.         ignore(write(macfd, (char *) &namelen, sizeof namelen));
  816.         ignore(write(macfd, m->Name, namelen));
  817.         ignore(write(macfd, m->Body, m->MacLength));
  818.     }
  819.     ignore(close(macfd));
  820. }
  821.  
  822. ReadMacs()
  823. {
  824.     char    *file;
  825.     FMACRO    *m;
  826.     int    macfd,
  827.         namelen,
  828.         bodylen;
  829.  
  830.     file = ask((char *) 0, FuncName());
  831.     if ((macfd = open(file, 0)) == -1)
  832.         complain(IOerr("open", file));
  833.  
  834.     while (nmacros < NMACROS) {
  835.         if (read(macfd, (char *) &bodylen, sizeof m->MacLength) == 0)
  836.             break;
  837.         m = (FMACRO *) emalloc (sizeof *m);
  838.         m->MacLength = bodylen;
  839.         m->MacBuflen = (m->MacLength + 16) & ~017;
  840.         ignore(read(macfd, (char *) &namelen, sizeof namelen));
  841.         m->Name = emalloc(namelen);
  842.         ignore(read(macfd, m->Name, namelen));
  843.         m->Body = emalloc(m->MacBuflen);
  844.         ignore(read(macfd, m->Body, m->MacLength));
  845.         DefMac(m->Name, m);
  846.     }
  847.     ignore(close(macfd));
  848. }
  849.  
  850. /*------------------------o.s. dependent------------------------*/
  851. /* end */
  852.